package org.keyroy.map_editor.map;

import java.io.File;

import org.keyroy.map_editor.map.layers.BuildingLayer;
import org.keyroy.map_editor.map.layers.CollideLayer;
import org.keyroy.map_editor.map.layers.FloorLayer;
import org.keyroy.map_editor.map.m.Point;
import org.keyroy.map_editor.map.m.Rect;
import org.keyroy.map_editor.ui.panels.MapPanel.MapEvent;
import org.keyroy.tag.Tag;
import org.keyroy.tag.XmlSupport;
import org.keyroy.util.file.FileUtil;

public class Map implements XmlSupport {

	private Point mapSize;
	private Rect gridSize;

	private File folder;

	public FloorLayer floorLayer;
	public BuildingLayer buildingLayer;
	public CollideLayer collideLayer;

	public MapResource resource;
	public boolean used45;
	public MapEvent mapEvent;

	public Map() {
		mapSize = new Point();
		gridSize = new Rect();

		floorLayer = new FloorLayer();
		buildingLayer = new BuildingLayer();
		collideLayer = new CollideLayer();

		resource = new MapResource();
	}

	public Map(File folder) throws Exception {
		this();
		this.folder = folder;
		FileUtil.load(folder, this);

	}

	public Map(int columns, int rows, int pWidth, int pHeight, File folder, boolean used45) {
		this();
		this.folder = folder;
		reset(columns, rows, pWidth, pHeight, used45);
	}

	public void reset(int columns, int rows, int pWidth, int pHeight, boolean used45) {
		this.used45 = used45;
		mapSize = new Point(columns, rows);
		gridSize = new Rect(pWidth, pHeight);

		initLang();
		init();
		save();
	}

	private void init() {
		floorLayer.setMap(this);
		collideLayer.setMap(this);
	}

	public final int getColumns() {
		return mapSize.x;
	}

	public final int getRows() {
		return mapSize.y;
	}

	private float hw, hh;
	private int pw, ph;

	public final float getHWidth() {
		return hw;
	}

	public final float getHHeight() {
		return hh;
	}

	public final int getPWidth() {
		return pw;
	}

	public final int getPHeight() {
		return ph;
	}

	public final int getGridWidth() {
		return gridSize.width;
	}

	public final int getGridHeight() {
		return gridSize.height;
	}

	private final void initLang() {
		hw = (float) gridSize.width / 2f;
		hh = (float) gridSize.height / 2f;

		if (used45) {
			pw = (mapSize.x + mapSize.y) * gridSize.width / 2;
		} else {
			pw = mapSize.x * gridSize.width;
		}

		if (used45) {
			ph = (mapSize.x + mapSize.y) * gridSize.height / 2;
		} else {
			ph = mapSize.y * gridSize.height;
		}
	}

	@Override
	public String getTagName() {
		return getClass().getSimpleName();
	}

	@Override
	public void initObj(Tag tag) {
		used45 = tag.getParameterBooleanValue("u45");
		mapSize = (Point) tag.getChildObject(Point.class);
		gridSize = (Rect) tag.getChildObject(Rect.class);
		if (mapSize == null || gridSize == null) {
			throw new IllegalArgumentException();
		}

		initLang();
		// init

		Tag resourceTag = tag.getChildTag(resource.getTagName());
		if (resourceTag != null) {
			resource.initObj(resourceTag);
		}

		Tag floorTag = tag.getChildTag(floorLayer.getTagName());
		if (floorTag != null) {
			floorLayer.setMap(this);
			floorLayer.initObj(floorTag);
		}

		Tag buildingLayerTag = tag.getChildTag(buildingLayer.getTagName());
		if (buildingLayerTag != null) {
			buildingLayer.initObj(buildingLayerTag);
		}

		Tag collideLayerTag = tag.getChildTag(collideLayer.getTagName());

		if (collideLayerTag != null) {
			collideLayer.initObj(collideLayerTag);
		}
	}

	@Override
	public void initTag(Tag tag) {
		tag.addParameter("u45", used45, used45);
		tag.addChild(mapSize);
		tag.addChild(gridSize);
		tag.addChild(floorLayer);
		tag.addChild(buildingLayer);
		tag.addChild(collideLayer);
		tag.addChild(resource);
	}

	public void save() {
		FileUtil.save(folder, this);
	}

	public final File getFolder() {
		return folder;
	}

	public final String getName() {
		if (folder != null) {
			return folder.getName();
		} else {
			return null;
		}
	}

}
